package cn.zyx.order.service.impl;

import cn.zyx.basic.service.impl.BaseServiceImpl;
import cn.zyx.basic.util.CodeGenerateUtils;
import cn.zyx.basic.util.DistanceUtil;
import cn.zyx.basic.util.PageList;
import cn.zyx.basic.util.Point;
import cn.zyx.order.domain.AdoptOrder;
import cn.zyx.order.domain.OrderAddress;
import cn.zyx.order.domain.ProductOrder;
import cn.zyx.order.domain.ProductOrderDetail;
import cn.zyx.order.mapper.OrderAddressMapper;
import cn.zyx.order.mapper.ProductOrderDetailMapper;
import cn.zyx.order.mapper.ProductOrderMapper;
import cn.zyx.order.query.ProductOrderQuery;
import cn.zyx.order.service.IProductOrderService;
import cn.zyx.org.domain.Employee;
import cn.zyx.org.domain.Shop;
import cn.zyx.org.mapper.EmployeeMapper;
import cn.zyx.org.mapper.ShopMapper;
import cn.zyx.pay.constants.PayConstants;
import cn.zyx.pay.domain.PayBill;
import cn.zyx.pay.mapper.PayBillMapper;
import cn.zyx.pay.service.IPayBillService;
import cn.zyx.pet.domain.Pet;
import cn.zyx.product.domain.Product;
import cn.zyx.product.mapper.ProductMapper;
import cn.zyx.user.domain.LoginInfo;
import cn.zyx.user.domain.User;
import cn.zyx.user.domain.UserAddress;
import cn.zyx.user.mapper.UserAddressMapper;
import cn.zyx.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class ProductOrderServiceImpl extends BaseServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private ProductOrderMapper productOrderMapper;
    @Autowired
    private ProductOrderDetailMapper productOrderDetailMapper;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private PayBillMapper payBillMapper;
    @Autowired
    private IPayBillService payBillService;
    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    @Transactional
    public String submit(Map<String, Object> params, LoginInfo loginInfo) {
        // 获取map中的参数
        Long productId = Long.valueOf(params.get("product_id").toString());                  // 获取服务的id
        Long addressId = Long.valueOf(params.get("address_id").toString());                  // 收货地址：t_user_address的id
        Integer serviceMethod = Integer.valueOf(params.get("service_method").toString());    // 送货方式
        Integer payMethod = Integer.valueOf(params.get("pay_method").toString());            // 1 支付宝 2 微信  3 银联 0 余额
        Integer productNum = Integer.valueOf(params.get("product_num").toString());          // 购买数量
        // 生成订单 -- 步骤
        // 通过服务的id查询服务
        Product product = productMapper.loadById(productId);
        // 绑定服务的用户
        User user = userMapper.loadByLoginInfoId(loginInfo.getId());
        // 分配最近的门店
        // 获取用户的地址
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        // 调用工具类把用户地址解析成为一个点
        Point point = DistanceUtil.getPoint(userAddress.getFullAddress());
        // 调用工具类，根据用户地址的点找到最近的店铺
        Shop nearestShop = DistanceUtil.getNearestShop(point, shopMapper.loadAll());
        // 自定义方法，生成服务订单的信息
        ProductOrder productOrder = getProductOrder(productId, productNum, product, user, nearestShop);
        // 生成支付唯一标识
        String unionPaySn = CodeGenerateUtils.generateUnionPaySn();
        productOrder.setPaySn(unionPaySn);
        // 保存订单信息
        productOrderMapper.save(productOrder);
        // 改销量
        Long num = product.getSalecount() + productNum;
        product.setSalecount(num);
        productMapper.update(product);
        // 生成订单详情 -- 防止下单之后服务信息变更带来的问题，特别是价格
        ProductOrderDetail productDetail = getProductDetail(product, productOrder, num);
        productOrderDetailMapper.save(productDetail);
        // 生成订单地址
        OrderAddress orderAddress = userAddress2OrderAddress(productOrder, userAddress);
        orderAddressMapper.save(orderAddress);
        // 生成支付单
        PayBill payBill = initPayBill(payMethod, user, nearestShop, productOrder);
        // 保存支付单
        payBillMapper.save(payBill);
        // 调用统一的支付接口完成支付
        String resultData = payBillService.pay(payBill);
        return resultData;
        // 订单超时取消@TODO
    }

    @Override
    public PageList<ProductOrder> queryAdmin(ProductOrderQuery query, Long loginInfoId) {
        //1.通过loginInfoId查询出Employee
        Employee employee = employeeMapper.loadByLoginInfoId(loginInfoId);
        //2.如果employee中的shopId不为null,就是店铺。否则就是平台员工
        if (employee.getShop_id() != null) {
            query.setShopId(employee.getShop_id());
        }
        return super.queryPage(query);
    }

    @Override
    public PageList<ProductOrder> queryUser(ProductOrderQuery query, Long loginInfoId) {
        // 查询当前用户信息
        User user = userMapper.loadByLoginInfoId(loginInfoId);
        // 给用户字段赋值
        query.setUserId(user.getId());
        return super.queryPage(query);
    }

    /**
     * 生成支付单
     * @param payMethod
     * @param user
     * @param nearestShop
     * @param productOrder
     * @return
     */
    private PayBill initPayBill(Integer payMethod, User user, Shop nearestShop, ProductOrder productOrder) {
        PayBill payBill = new PayBill();
        payBill.setDigest(productOrder.getDigest()+"支付单");
        payBill.setMoney(productOrder.getPrice());
        payBill.setUnionPaySn(productOrder.getPaySn());     // 支付唯一标识
        payBill.setState(0);                                // 0待支付 1已支付 -1 取消
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + PayConstants.LAST_TIME));
        payBill.setPayChannel(Long.valueOf(payMethod));     // 支付渠道
        payBill.setBusinessType(PayConstants.BUSINESS_TYPE_PRODUCT); // 服务支付单
        payBill.setBusinessKey(productOrder.getId());
        payBill.setUser_id(user.getId());
        payBill.setShop_id(nearestShop.getId());            // 最近的店铺id
        payBill.setNickName(user.getUsername());
        return payBill;
    }

    /**
     * 生成订单地址
     * @param productOrder
     * @param userAddress
     * @return
     */
    private OrderAddress userAddress2OrderAddress(ProductOrder productOrder, UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        orderAddress.setId(null);
        orderAddress.setOrder_id(productOrder.getId());
        orderAddress.setOrderSn(productOrder.getOrderSn());
        return orderAddress;
    }

    /**
     * 生成服务详情
     * @param product
     * @param productOrder
     * @param num
     * @return
     */
    private ProductOrderDetail getProductDetail(Product product, ProductOrder productOrder, Long num) {
        ProductOrderDetail productOrderDetail = new ProductOrderDetail();
        BeanUtils.copyProperties(product, productOrderDetail);
        productOrderDetail.setId(null);
        productOrderDetail.setSalecount(num);
        productOrderDetail.setOrder_id(productOrder.getId());
        return productOrderDetail;
    }

    /**
     * 获取服务订单信息
     * @param productId
     * @param productNum
     * @param product
     * @param user
     * @param nearestShop
     */
    private ProductOrder getProductOrder(Long productId, Integer productNum, Product product, User user, Shop nearestShop) {
        ProductOrder productOrder = new ProductOrder();
        // 摘要
        productOrder.setDigest("[摘要]服务"+product.getName()+"的订单！");
        // 0 待支付 1 已支付
        productOrder.setState(0);
        // 总价 -- 总价 = 售价 * 购买数量 -- BigDecimal算法需要调用它的方法
        productOrder.setPrice(product.getSaleprice().multiply(new BigDecimal(productNum)));
        // 订单唯一标识
        productOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(product.getId()));
        // 最后确定时间 -- 15分钟自动取消
        Date lastConfirmTime = new Date(System.currentTimeMillis() + 15*60*1000);
        productOrder.setLastConfirmTime(lastConfirmTime);
        // 服务id
        productOrder.setProduct_id(productId);
        // 用户id
        productOrder.setUser_id(user.getId());
        // 商店id
        productOrder.setShop_id(nearestShop.getId());
        // 返回
        return productOrder;
    }


    /*@Autowired
    private ProductOrderMapper productOrderMapper;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;

    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductOrderDetailMapper productOrderDetailMapper;

    @Autowired
    private PayBillMapper payBillMapper;

    @Autowired
    private IPayBillService payBillService;
    @Autowired
    private IQuartzService quartzService;
    @Override
    public String submit(Map<String, Object> params, User user) {
        Long addressId = Long.parseLong(params.get("address_id").toString());
        Long productId = Long.parseLong(params.get("product_id").toString());
        Long pay_method = Long.parseLong(params.get("pay_method").toString());
        Product product = productMapper.loadById(productId);
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        System.out.println(userAddress);
        //1创建订单
        //1.1 创建订单
        ProductOrder productOrder = getProductOrder(params,userAddress,product,user);
        productOrderMapper.save(productOrder);
        //1.2 保存关联表 orderAdress productOrderDetail

        System.out.println(productOrder.getId());
        OrderAddress orderAddress = userAddress2orderAddress(userAddress);
        orderAddress.setOrder_id(productOrder.getId());
        orderAddress.setOrderSn(productOrder.getOrderSn());
        orderAddressMapper.save(orderAddress);

        ProductOrderDetail productOrderDetail = product2productOrderDetail(product);
        productOrderDetail.setOrder_id(productOrder.getId());
        productOrderDetailMapper.save(productOrderDetail);

        // 2 创建支付单
        PayBill payBill = order2PayBill(pay_method, productOrder, user);
        payBillMapper.save(payBill);

        // 3 订单倒计时取消处理
        QuartzJobInfo info = new QuartzJobInfo();
        info.setType(JobTypeConsts.WAIT_PRODUCT_ORDER_PAY_CANCEL_JOB);
        String jobName = "ProductOrderCancelJob"+productOrder.getId();
        Map<String, Object> infoParams = new HashMap<>();
        infoParams.put("orderId",productOrder.getId());
        Date fireDate = productOrder.getLastPayTime();
        info.setJobName(jobName);
        info.setParams(infoParams);
        info.setFireDate(fireDate);
        quartzService.addJob(info);
        // 4 跳转到支付页面,通过调用支付接口，要把这个数据返回前台，前台处理后跳转支付宝支付页面
        String payData = payBillService.pay(payBill);
        return payData;
    }

    @Override
    public void cancelOrder(Long orderId) {
        ProductOrder productOrder = productOrderMapper.loadById(orderId);
        if(productOrder.getState()!=-1){
            productOrder.setState(-1);
            productOrderMapper.update(productOrder);
        }

        String paySn = productOrder.getPaySn();
        PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
        if (payBill.getState()!=-1){
            payBill.setState(-1);
            payBillMapper.update(payBill);
        }

    }

    private PayBill order2PayBill(Long pay_method, ProductOrder productOrder,User user) {
        PayBill payBill = new PayBill();
        payBill.setDigest(productOrder.getDigest());
        payBill.setMoney(productOrder.getPrice());
        payBill.setUnionPaySn(productOrder.getPaySn());
        payBill.setState(0);
        payBill.setLastPayTime(productOrder.getLastPayTime());
        payBill.setPayChannel(pay_method);
        payBill.setBusinessType(PayConstants.BUSINESSTYPE_PRODUCT);
        payBill.setBusinessKey(productOrder.getId());
        payBill.setCreateTime(new Date());
        payBill.setUser_id(productOrder.getUser_id());
        payBill.setNickName(user.getUsername());
        payBill.setShop_id(productOrder.getShop_id());
        return payBill;
    }

    private ProductOrderDetail product2productOrderDetail(Product product) {
        ProductOrderDetail productOrderDetail = new ProductOrderDetail();
        BeanUtils.copyProperties(product,productOrderDetail);
        return productOrderDetail;
    }

    private OrderAddress userAddress2orderAddress(UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);
        orderAddress.setContacts(userAddress.getContacts());
        return orderAddress;
    }

    @Autowired
    private ShopMapper shopMapper;
    private ProductOrder getProductOrder(Map<String, Object> params,UserAddress userAddress,Product product, User user) {
        Long productNum = Long.parseLong(params.get("product_num").toString());
        ProductOrder productOrder = new ProductOrder();

        productOrder.setDigest("[服务订单]购买"+productNum+"次"+product.getName()+"服务！");
        productOrder.setState(0);
        BigDecimal price  = product.getSaleprice().multiply(new BigDecimal(100))
                .multiply(new BigDecimal(productNum));
        productOrder.setPrice(price);
        productOrder.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        Date lastPayTime = new Date(System.currentTimeMillis()+60*1000); //当前时间+30分钟
        productOrder.setLastPayTime(lastPayTime);
        productOrder.setProduct_id(product.getId());
        productOrder.setUser_id(user.getId());
        Shop nearestShop = DistanceUtil.getNearestShop(DistanceUtil.getPoint(userAddress.getFullAddress()), shopMapper.loadAll());
        productOrder.setShop_id(nearestShop.getId());
        productOrder.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        return productOrder;
    }
*/
}
